package com.lzh.chatnote.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.lzh.chatnote.common.constant.MQConstant;
import com.lzh.chatnote.common.constant.RedisKey;
import com.lzh.chatnote.common.domain.dto.LoginMessageDTO;
import com.lzh.chatnote.common.mqProducer.MQProducer;
import com.lzh.chatnote.common.utils.RedisUtils;
import com.lzh.chatnote.user.dao.UserDao;
import com.lzh.chatnote.user.domain.entity.AuthData;
import com.lzh.chatnote.user.domain.entity.User;
import com.lzh.chatnote.user.service.ThreeLoginService;
import com.lzh.chatnote.user.service.UserService;
import com.lzh.chatnote.user.service.adapter.UserAdapter;
import com.lzh.chatnote.webSocket.enums.LoginTypeEnum;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ThreeLoginServiceImpl implements ThreeLoginService {
    private final static String CALL_BACK_URL = "http://localhost:8080/login";
    @Resource
    private UserDao userDao;
    @Resource
    private UserService userService;
    @Resource
    private MQProducer mqProducer;

    @SneakyThrows
    @Override
    public void login(HttpServletResponse response, String source, AuthResponse<AuthData> authResponse, String code) {
        if (Objects.isNull(authResponse.getData())) {
            log.info("用户取消了授权{}", new Date());
            response.sendRedirect(CALL_BACK_URL);
            return;
        }
        AuthData authData = JSONUtil.toBean(JSONUtil.toJsonStr(authResponse.getData()), AuthData.class);
        //第三方授权无效
        Optional.ofNullable(authData.getUuid()).orElseThrow(() -> new RuntimeException("第三方授权登录失败"));
        User user = userDao.getUserByOpenId(authData.getUuid());
        if (Objects.nonNull(user)) {
            //当前用户已经注册了，尝试进行登录
            //todo 用户登录
            mqProducer.sendMsg(MQConstant.LOGIN_MSG_TOPIC, new LoginMessageDTO(user.getId(), Integer.valueOf(code)));
            //会调地址
            response.sendRedirect(CALL_BACK_URL);
            return;
        }
        //填充用户信息
        user = fillUserInfo(authData, source);
        //保存用户账号和token的关联
        RedisUtils.set(RedisKey.getKey(RedisKey.USER_TOKEN, authData.getUuid()), code, 30, TimeUnit.MINUTES);
        //尝试用户登录
        mqProducer.sendMsg(MQConstant.LOGIN_MSG_TOPIC, new LoginMessageDTO(user.getId(), Integer.valueOf(code)));
        //会调地址
        response.sendRedirect(CALL_BACK_URL);
    }

    private User fillUserInfo(AuthData authData, String loginType) {
        for (int i = 0; i < 6; i++) {
            User user = UserAdapter.fillThreeUserInfo(authData, loginType);
            try {
                userDao.save(user);
                return user;
            } catch (DuplicateKeyException e) {
                log.info("用户名字重复:{},用户信息为:{}", user.getOpenId(), user);
            } catch (Exception e) {
                log.error("保存用户信息失败{}", user);
                throw new RuntimeException(e);
            }
            user.setName("名字重置" + RandomUtil.randomInt(100000));
        }
        throw new RuntimeException("用户注册失败");
    }
}
